#include "TriangleSoupVoxel.h"
#include <iostream>

using namespace std;

// Constructor
TriangleSoupVoxel::TriangleSoupVoxel(void)
{
	init();
}

TriangleSoupVoxel::TriangleSoupVoxel(float size, int depth, int nodeId, TriangleSoupVoxel* parent, float x, float y, float z) {
	init();
	m_size = size;
	m_distance = 0.0;
	m_depth = depth;
	m_x = x;
	m_y = y;
	m_z = z;
	_sibling = new TriangleSoupVoxel*[8];
	_parent = parent;
	_nodeId = nodeId;
	for(int i = 0; i < 8; i++) {
		_sibling[i] = 0;
	}	

	//std::cout << std::endl;
#ifdef BEVERBOSE
	if(parent) {
		std::cout << "COARSE voxel #" << nodeId << " at (" << x << " " << y << " " << z << ") of depth " << depth << std::endl;
	} else {
		std::cout << "_ROOT_ COARSE voxel #" << nodeId << " at (" << x << " " << y << " " << z << ")" << depth << std::endl;
	}
#endif
}

// Destructor
TriangleSoupVoxel::~TriangleSoupVoxel(void)
{
	cout << "TriangleVoxel:: ~" << endl;
	_parent = NULL;
	if(_enclosedTriangleSoup != NULL)
	{
		delete _enclosedTriangleSoup;
	}
	for(int i = 0; i < 8; i++)
	{
		if(_sibling[i] != NULL)
		{
			delete _sibling[i];
		}
	}
	delete[] _sibling;
}

/* METHODS */

void TriangleSoupVoxel::init() {
	_final = true;
	_nodeId = -1;
	_numChildren = 0;
	_enclosedTriangleSoup = NULL;
}

void TriangleSoupVoxel::setEnclosedTriangleSoup(std::vector<float> verticesVector, std::vector<int> trianglesVector) {
	_enclosedTriangleSoup = new MeshStruct(verticesVector, trianglesVector);
}

// real number of triangles (no multiplicaiton by x3)
int TriangleSoupVoxel::getTriNum() {
	if(_enclosedTriangleSoup)
	{
		return _enclosedTriangleSoup->m_nTri / 3;
	}
	else
	{
		return 0;
	}
}

// real number of vertices (no multiplication x3)
int	TriangleSoupVoxel::getVertNum() {
	if(_enclosedTriangleSoup) 
	{
		return _enclosedTriangleSoup->m_nGeom / 3;
	}
	else
	{
		return 0;
	}
}

float* TriangleSoupVoxel::getVerts() {
	if(_enclosedTriangleSoup)
	{
		return _enclosedTriangleSoup->m_geom;
	}
	else
	{
		return 0;
	}
}

int* TriangleSoupVoxel::getTris() {
	if(_enclosedTriangleSoup)
	{
		return _enclosedTriangleSoup->m_tri;
	} else 
	{
		return 0;
	}
}

bool TriangleSoupVoxel::isFinal() {
	return _final;
}

void TriangleSoupVoxel::setStillBorn(TriangleSoupVoxel* stillbornVoxel) {
	// (1) Set stillborn
	int nodeId = stillbornVoxel->getNodeId();
	_sibling[nodeId] = 0;
	delete(stillbornVoxel);

	//std::cout << std::endl <<  "***********************  STILLBORN   ********************" << std::endl;

	// (2) If it was the last valid child
	if( !(--_numValidChild) ) {
		( this->getParent() )->setStillBorn( this );
	}
}

int	TriangleSoupVoxel::getNodeId() {
	return _nodeId;
}

int	TriangleSoupVoxel::increaseNumChildren() {
	_numChildren++;
	return ( (_numChildren < 8) ? _numChildren : 7);
}

TriangleSoupVoxel* TriangleSoupVoxel::getParent() {
	return _parent;
}